<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>对象的扩展</title>
</head>
<body>
    对象：属性和方法的集合  创建对象的方式
    对象新增特性
    <!-- 
        1.对象属性简写/函数(方法)的简写
            属性名简写 当属性名与属性值同名时则可以简写
            直接省略冒号及function关键词
        2.对象的属性名表达式  key
            解决对象的属性名只能为固定的字符串
        3.对象方法
            Object.is():它用来比较两个值是否严格相等    ==  ===  Object.is()的区别
                在===基础上特别处理了NaN,-0,+0,保证-0与+0不相等，但NaN与NaN相等
            Object.keys():返回一个包含所有给定对象自身可枚举属性名称的数组。
            Object.values():返回给定对象自身可枚举值的数组。
            Object.entries():返回给定对象自身可枚举属性的 [key, value] 数组。
            Object.freeze():冻结对象：用于冻结一个对象。即将对象设置为不可扩展、将对象的所有自有的属性和方法（包括Symbol值的属性和方法）配置为不可配置、不可写。
            Object.assign():通过复制一个或多个对象来创建一个新的对象。  浅拷贝 
            Object.create():使用指定的原型对象和属性创建一个新对象。
            Object.defineProperty():给对象添加一个属性并指定该属性的配置。
     -->

    <script>

         // es6  1: 对象属性简写/函数(方法)的简写

        // es5

        // let age = 10;

        // let obj = {
        //     name:"jack",
        //     age:age,
        //     getInfo:function(){
        //         console.log(this.name+this.age);    
        //     }
        // }

        // es6
        let age = 10;

        let obj = {
            name:"jack",
            age,
            getInfo(){
                console.log(this.name+this.age);    
            }
        }
        console.log(obj);
        

        // 2.解决对象的属性名只能为固定的字符串->对象的属性只能用字符串类型   key丰富写法 
        // 之前定义对象的时候，对象中的属性（key）名字的取值范围都是string类型,现在我们可以通过
        // ES6新增的变量表示法来丰富属性（key）类型
        
        let sex="男"
        let flag = true;
        let fn = function () {
            
        }

        let obj2 = {
            id: 1000,
            [sex]:"性别",
            [flag]:"标志位",
            [fn]:"我是一个函数类型的key"

        }

        console.log(obj2);
        
         //  3.对象方法  Object.is():它用来比较两个值是否严格相等    ==  ===  Object.is()的区别
                // 在===基础上特别处理了NaN,-0,+0,保证-0与+0不相等，但NaN与NaN相等

        console.log(null == undefined);//==  先进行隐式类型转换 0  在比较值
        console.log(100 == "100");//  先进行隐式类型转换  100  
        console.log(null === undefined);//===  数据类型及值 0  在比较值
        console.log(100 === "100");//    100  
        console.log(+0 === -0);//  
        console.log(NaN === NaN);//  js当中唯一不等于自身的一个值

        console.log(Object.is(+0,-0));
        console.log(Object.is(NaN,NaN));
        

        // Object.keys():返回一个包含所有给定对象自身可枚举属性名称的数组。
        // Object.values():返回给定对象自身可枚举值的数组。
        // Object.entries():返回给定对象自身可枚举属性的 [key, value] 数组。

        console.log('当前对象中的key的集合是：', Object.keys(obj))//[name,age,getInfo]
        console.log('当前对象中的value的集合是：', Object.values(obj))//[jack,10,f]
        console.log('当前对象中的键值对的集合是：', Object.entries(obj))//[[name:jack],[age:10],[getInfo:f]]

        // Object.freeze():冻结对象：用于冻结一个对象。即将对象设置为不可扩展、将对象的所有自有的属性和方法（包括Symbol值的属性和方法）配置为不可配置、不可写。
        let arr = [1,2,3,4,5]
        Object.freeze(arr)
        // arr.push(6)
        // arr.push(7)
        // arr.shift()
        // arr.shift()

        console.log(arr);
        
        // Object.assign():通过复制一个或多个对象来创建一个新的对象。  浅拷贝 
        // Object.create():使用指定的原型对象和属性创建一个新对象。
        let obj3 = Object.assign({},obj)
        console.log(obj3);
        
        console.log(Object.create(null));


        // Object.defineProperty():给对象添加一个属性并指定该属性的配置
        
        Object.defineProperty(obj,"hobby",{
            set(){
                console.log("set方法");
                
            },
            get(){
                console.log("get方法");
            }
        })

        console.log(obj.name);
        

        var obj4 = {
            a: 1,
            get next() { return this.a++; },
            set next(value) { 
                if (value >= this.a) { 
                    this.a = value;
                }
            }
        };

        console.log(Object.getOwnPropertyDescriptors(obj4));
        console.log(obj4.next);//1   ++  --  在后  先返回表达式的值  在自增1  在前 先自增1 在返回表达式的值
        console.log(obj4.next);//2   ++  -- 
        console.log(obj4.a);//3
        Object.freeze(obj4)//冻结
        console.log(Object.getOwnPropertyDescriptors(obj4));
        console.log(obj4.next);//
        console.log(obj4.next);//
        console.log(obj4.a);//3

        obj4.next = 100;
        console.log(obj4.next);//3
        console.log(obj4.a);//3
    </script>
    
</body>
</html>